using System;
using System.Threading.Tasks;
using System.Collections.Generic;
using System.Linq;
using Microsoft.EntityFrameworkCore;
using Terra.Data.Context;
using Terra.Data.Entities.Identity;
using Terra.Data.Repository;

namespace Terra.Data.Repository.Identity;

/// <summary>
/// 密码重置令牌仓储实现
/// </summary>
public class PasswordResetTokenRepository : RepositoryBase<PasswordResetToken, Guid>, IPasswordResetTokenRepository
{
    private readonly TerraDbContext _terraDbContext;

    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="context">数据库上下文</param>
    public PasswordResetTokenRepository(TerraDbContext context) : base(context)
    {
        _terraDbContext = context;
    }

    /// <summary>
    /// 根据令牌查找（使用Join方式）
    /// </summary>
    public async Task<PasswordResetToken> FindByTokenAsync(string token)
    {
        // 方式1：使用Join
        var result = await (
            from t in _dbSet
            join u in _terraDbContext.Set<User>() on t.UserId equals u.Id
            where t.Token == token
            select new PasswordResetToken
            {
                Id = t.Id,
                Token = t.Token,
                UserId = t.UserId,
                CreatedTime = t.CreatedTime,
                ExpiresTime = t.ExpiresTime,
                IsUsed = t.IsUsed,
                UsedTime = t.UsedTime,
                User = u
            }).FirstOrDefaultAsync();

        return result;
    }

    /// <summary>
    /// 获取用户的所有重置令牌（使用LINQ方式）
    /// </summary>
    /// <param name="userId">用户ID</param>
    /// <returns>重置令牌列表，包含用户信息</returns>
    public async Task<List<PasswordResetToken>> GetUserTokensWithDetailsAsync(Guid userId)
    {
        // 方式1：使用LINQ查询语法
        var query = from token in _dbSet
                    join user in _terraDbContext.Set<User>() on token.UserId equals user.Id
                    where token.UserId == userId
                    orderby token.CreatedTime descending
                    select new PasswordResetToken
                    {
                        Id = token.Id,
                        Token = token.Token,
                        UserId = token.UserId,
                        CreatedTime = token.CreatedTime,
                        ExpiresTime = token.ExpiresTime,
                        IsUsed = token.IsUsed,
                        UsedTime = token.UsedTime,
                        User = new User
                        {
                            Id = user.Id,
                            UserName = user.UserName,
                            Email = user.Email,
                            PhoneNumber = user.PhoneNumber
                        }
                    };

        return await query.ToListAsync();
    }



    /// <summary>
    /// 验证令牌有效性
    /// </summary>
    public async Task<(bool isValid, Guid userId)> ValidateTokenAsync(string token)
    {
        var resetToken = await FindByTokenAsync(token);

        if (resetToken == null)
        {
            return (false, Guid.Empty);
        }

        // 检查令牌是否已使用
        if (resetToken.IsUsed)
        {
            return (false, Guid.Empty);
        }

        // 检查令牌是否过期
        if (DateTime.UtcNow > resetToken.ExpiresTime)
        {
            return (false, Guid.Empty);
        }

        return (true, resetToken.UserId);
    }

    /// <summary>
    /// 使令牌失效
    /// </summary>
    public async Task InvalidateTokenAsync(string token)
    {
        var resetToken = await FindByTokenAsync(token);
        if (resetToken != null)
        {
            resetToken.IsUsed = true;
            resetToken.UsedTime = DateTime.UtcNow;
            await UpdateAsync(resetToken);
        }
    }

    /// <summary>
    /// 清理过期令牌
    /// </summary>
    public async Task CleanupExpiredTokensAsync()
    {
        var expiredTokens = await _dbSet
            .Where(x => x.ExpiresTime < DateTime.UtcNow)
            .ToListAsync();

        if (expiredTokens.Any())
        {
            _dbSet.RemoveRange(expiredTokens);
            await _dbContext.SaveChangesAsync();
        }
    }

    
}